//
// Created by zhouwd on 2019/7/23.
//


#include "media_audio_decode.h"


int _MEDIA_AUDIO_DECODE::startDecode() {

    return 0;
}

int _MEDIA_AUDIO_DECODE::init(const char *filename) {
    extractor = AMediaExtractor_new();

    media_status_t mediaAudioDataSource = AMediaExtractor_setDataSource(extractor, filename);

    if (mediaAudioDataSource != AMEDIA_OK) {
        return -3;
    }

    size_t audioTrackCount = AMediaExtractor_getTrackCount(extractor);

    if (audioTrackCount <= 0) {
        return -4;
    }

    for (size_t i = 0; i < audioTrackCount; ++i) {

        AMediaFormat *format = AMediaExtractor_getTrackFormat(extractor, i);


        const char* s;

        AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &s);

        ALOGE("MediaExtractor > init > %s", s);

        if (strncmp(s, "audio/" , 6) == 0) {
            media_status_t trackStatus = AMediaExtractor_selectTrack(extractor, i);
            //ALOGE("MediaExtractor > trackStatus > audio > %d", trackStatus);

            int32_t audioChannels;

            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &audioChannels);

            ALOGE("MediaExtractor > audio > channelCount > %d", audioChannels);

            int32_t audioSampleRate;

            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &audioSampleRate);

            ALOGE("MediaExtractor > audio > sampleRate > %d", audioSampleRate);



            int32_t maxInputSize;

            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, &maxInputSize);

            ALOGE("MediaExtractor > audio > inputSize > %d", maxInputSize);

            audioCodec = AMediaCodec_createDecoderByType(s);

            media_status_t audioRc =AMediaCodec_configure(audioCodec, format, NULL, NULL, 0);

            ALOGE("MediaExtractor > audio > audioRc > %d", audioRc);
            //mediaAudioData->init(audioCodec);
            AMediaCodec_start(audioCodec);

        }

    }


    return 0;
}

_MEDIA_AUDIO_DECODE::_MEDIA_AUDIO_DECODE() {

}

_MEDIA_AUDIO_DECODE::~_MEDIA_AUDIO_DECODE() {

}

int _MEDIA_AUDIO_DECODE::getPcm(void **pcm, size_t *pcm_size) {

    bool isMediaEOS = false;

    while (!isMediaEOS) {
        ssize_t inputBufferIndex = AMediaCodec_dequeueInputBuffer(audioCodec, 1000);

        if (inputBufferIndex >= 0) {
            // 获取buffer的索引
            size_t out_size;

            uint8_t *inputBuf = AMediaCodec_getInputBuffer(audioCodec, inputBufferIndex, &out_size);


            ssize_t sampleSize = AMediaExtractor_readSampleData(extractor, inputBuf, out_size);
            //ALOGE("_MEDIA_AUDIO_DECODE > run > sampleSize > %d", sampleSize);
            if (sampleSize < 0 ) {
                sampleSize = 0;
                //AMediaCodec_queueInputBuffer(audioCodec, inputBufferIndex, 0, 0, 0, AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM);
                isMediaEOS = true;
                //mediaAudioData->setStop();
            }


            int64_t presentationTimeUs = AMediaExtractor_getSampleTime(extractor);
            ALOGE("_MEDIA_AUDIO_DECODE > run > presentationTimeUs > %lld" ,presentationTimeUs);
            //usleep(presentationTimeUs / 1000);
            media_status_t status = AMediaCodec_queueInputBuffer(audioCodec, inputBufferIndex, 0, sampleSize, presentationTimeUs,isMediaEOS ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0);
            AMediaExtractor_advance(extractor);

        }

        AMediaCodecBufferInfo info;

        int status = AMediaCodec_dequeueOutputBuffer(audioCodec, &info, 1);

        //ALOGE("dequeueOutputBuffer returned: %d", status);

        if (status >= 0) {
            if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) {
                isMediaEOS = true;
            }
            size_t outsize;
            uint8_t *outputBuf = AMediaCodec_getOutputBuffer(audioCodec, status, &outsize);
            ALOGE("_MEDIA_AUDIO_DECODE > run > outputBuf > outsize > %d" ,info.size);
            if (outputBuf != nullptr) {

                isMediaEOS = true;
                *pcm = outputBuf;
                *pcm_size = info.size;
            }
            AMediaCodec_releaseOutputBuffer(audioCodec, status, true);
            //ALOGE("_MEDIA_AUDIO_DECODE returned: > 0");
        } else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) {
            //ALOGE("_MEDIA_AUDIO_DECODE returned: AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED");
        } else if(status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {
            // ALOGE("_MEDIA_AUDIO_DECODE returned: AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED");
        } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
            //ALOGE("_MEDIA_AUDIO_DECODE returned: AMEDIACODEC_INFO_TRY_AGAIN_LATER");
        } else {
            //ALOGE("_MEDIA_AUDIO_DECODE returned: else");
        }

    }

    return 0;
}
